#pragma once
#include "ETF.hpp"
#include "Stock.hpp"

namespace StockMarket
{
    class Stock;
    class ETF;

    class Market
    {
    private:
        std::unordered_map<int, std::shared_ptr<Stock>> m_stocks;
        std::unordered_map<int, std::shared_ptr<ETF>> m_etfs;

    public:
        void createStock(int stock, int price)
        {
            m_stocks[stock] = std::make_shared<Stock>(stock, price);
        }

        /**
         * @brief 从申购赎回清单文件创建ETF
         *
         */
        void createETF(const std::string &path)
        {
            PurchaseRedemptionList list;
            auto l = list.read(path);
            for (const auto &e : l)
            {
                createStock(e.code, 0); // 就先假设所有股票的价格都是0
            }
            createETF(159915, l);
        }

        // must create stock first
        void createETF(int etf_code, const std::vector<PurchaseRedemptionEntry> &list)
        {
            auto etf = std::make_shared<ETF>(etf_code);

            for (auto &entry : list)
            {
                m_stocks[entry.code]->addETF(etf);
                etf->addStock(entry.code, m_stocks[entry.code]);
            }

            etf->addStock(list);
            m_etfs[etf_code] = etf;
        }

        inline std::weak_ptr<ETF> getETF(int etf_code)
        {
            return m_etfs[etf_code];
        }

        void updateStockPrice(int stock, int price)
        {
            auto it = m_stocks.find(stock);
            if (it == m_stocks.end())
            {
                createStock(stock, price);
            }
            m_stocks[stock]->updatePrice(price); // 会自动更新etf的iopv
        }

        inline long long queryIOPV(int etf_code) const
        {
            return m_etfs.at(etf_code)->getIOPV();
        }
    };

} // namespace StockMarket
